package com.share.util;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

/**
 * String 操作的工具类
 *
 * @author 博博大人
 * @time 2018/12/14 12:00
 */
public class StringUtils {
	private static String[] binaryArray = { "0000", "0001", "0010", "0011",
			"0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
			"1100", "1101", "1110", "1111" };
	private static String[] chineseDigits = new String[] { "零", "壹", "贰", "叁",
			"肆", "伍", "陆", "柒", "捌", "玖" };

	private static final char[] charBytes = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
			'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
			'x', 'y', 'z' };

	private static final char[] numberBytes = { '0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9' };

	/**
	 * 生成指定位数的随机数子.
	 *
	 * @param number
	 * @return
	 */
	public static String randomNumbers(int number) {
		// 生成的密码的长度
		int count = 0;
		int i; // 生成的随机数
		final int maxNum = numberBytes.length;
		StringBuffer randomStr = new StringBuffer("");
		Random r = new Random();
		while (count < number) {
			// 生成随机数，取绝对值，防止生成负数，
			i = Math.abs(r.nextInt(maxNum)); // 生成的数最大为36-1
			if (i >= 0 && i < numberBytes.length) {
				randomStr.append(numberBytes[i]);
				count++;
			}
		}
		return randomStr.toString();
	}

	/**
	 * 判断list是否不为空
	 * 
	 * @param list
	 * @return
	 */
	public static boolean isNotNullToArray(List<?> list) {
		if (list.size() != 0 && !list.equals("") && list != null) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断是否为空
	 * 
	 * @param list
	 * @return
	 */
	public static boolean isNullToArray(List<?> list) {
		return !isNotNullToArray(list);
	}

	/**
	 * 判断是否为空 为空true 否则false
	 * 
	 * @param str
	 *            传入的字符串
	 * @return
	 */
	public static Boolean isNull(String str) {
		if (str == null || str.length() == 0 || str.equals("")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断是否不为空 为空false 空true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNotNull(String str) {
		return !isNull(str);
	}

	public static String randomStrByNumber(int number) {
		int count = 0; // 生成的密码的长度
		int i; // 生成的随机数
		final int maxNum = charBytes.length;
		StringBuffer randomStr = new StringBuffer("");
		Random r = new Random();
		while (count < number) {
			// 生成随机数，取绝对值，防止生成负数，
			i = Math.abs(r.nextInt(maxNum)); // 生成的数最大为36-1
			if (i >= 0 && i < charBytes.length) {
				randomStr.append(charBytes[i]);
				count++;
			}
		}
		return randomStr.toString();
	}

	public static String randomUUID() {
		UUID uuid = UUID.randomUUID();
		return uuid.toString().replace("-", "").toUpperCase();
	}

	public static String digitsTochinese(int i) {
		// 大于10的需要重写
		return chineseDigits[i];
	}

	public static String toAllUpperCase(String uuid) {
		StringBuffer buffer = new StringBuffer();

		for (int i = 0; i < uuid.length(); i++) {
			char c = uuid.charAt(i);
			if (Character.isLowerCase(c)) {
				buffer.append(Character.toUpperCase(c));
			} else {
				buffer.append(c);
			}
		}
		return buffer.toString();
	}

	// 十六进制字符串转byte数组
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4
					| charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	// 数组转字符串、以空格间隔
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			if (i == src.length - 1) {
				stringBuilder.append(hv);
			} else {
				stringBuilder.append(hv);
			}
		}
		return stringBuilder.toString();
	}

	public static String bytesToHexStringNoAppendBit(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			/*
			 * if (hv.length() < 2) { stringBuilder.append(0); }
			 */
			if (i == src.length - 1) {
				stringBuilder.append(hv);
			} else {
				stringBuilder.append(hv);
			}
		}
		return stringBuilder.toString();
	}

	public static String bytesToString(byte[] src, String split) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = String.valueOf(v);
			if (i == src.length - 1) {
				stringBuilder.append(hv);
			} else {
				stringBuilder.append(hv + split);
			}
		}
		return stringBuilder.toString();
	}

	public static String generateHexString(int paramInt) {
		StringBuffer localStringBuffer = new StringBuffer();
		Random localRandom = new Random();
		int i = 16;
		for (int j = 0; j < paramInt; j++) {
			if (j % 2 == 0) {
				localStringBuffer.append(
						"0123456789ABCDEF".charAt(localRandom.nextInt(i)));
			} else {
				localStringBuffer.append(
						"0123456789ABCDEF".charAt(localRandom.nextInt(i))
								+ " ");
			}
		}
		return localStringBuffer.toString();
	}

	public static byte[] decodeTripleDES(byte[] data, byte[] key)
			throws NoSuchAlgorithmException, NoSuchPaddingException,
			InvalidKeyException, IllegalBlockSizeException,
			BadPaddingException {
		byte[] keys;
		if (key.length == 16) {
			keys = new byte[24];
			System.arraycopy(key, 0, keys, 0, 16);
			System.arraycopy(key, 0, keys, 16, 8);
		} else {
			keys = key;
		}

		Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
		SecretKey secretKey = new SecretKeySpec(keys, "DESede");
		cipher.init(Cipher.DECRYPT_MODE, secretKey);
		return cipher.doFinal(data);
	}

	public static boolean equals(byte[] b1, byte[] b2) {
		if (b1.length != b2.length) {
			return false;
		}
		for (int i = 0; i < b1.length; i++) {
			if (b1[i] != b2[i]) {
				return false;
			}
		}
		return true;
	}

	/**
	 * @return 转换为二进制字符串
	 */
	public static String bytes2BinaryStr(byte[] bArray) {
		String outStr = "";
		int pos = 0;
		for (byte b : bArray) {
			// 高四位
			pos = (b & 0xF0) >> 4;
			outStr += binaryArray[pos];
			// 低四位
			pos = b & 0x0F;
			outStr += binaryArray[pos];
		}
		return outStr;
	}

	/**
	 * 将二进制转换成16进制 * @param buf * @return
	 */
	public static String binaryToHexString(byte[] bytes) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(bytes[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}

	/**
	 * 将16进制转换为二进制 * @param hexStr * @return
	 */
	public static byte[] hexStringToBinary(String hexStr) {
		if (hexStr.length() < 1)
			return null;
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
					16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}

	// 十六进制转为字符
	public static String hexStringToString(String s) {
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff
						& Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			s = new String(baKeyword, "utf-8");// UTF-16le:Not
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}

	/**
	 * 给某个日期加几天后的日期 eg:2013-06-28号+1天是 2013-06-29 ，+3天是2013-07-01
	 *
	 * @param date
	 *            日期
	 * @param dump
	 *            数字
	 * @return
	 */
	public static String getDateByAddSomeDay(Date date, int dump) {
		Calendar ca = Calendar.getInstance();
		SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd"); // 构造任意格式
		String today = sm.format(date);
		String[] timeArray = today.split("-");
		ca.set(Calendar.YEAR, Integer.parseInt(timeArray[0]));
		ca.set(Calendar.MONTH, Integer.parseInt(timeArray[1]) - 1);
		ca.set(Calendar.DAY_OF_MONTH, Integer.parseInt(timeArray[2]));
		ca.add(Calendar.DAY_OF_MONTH, dump);
		String someDay = sm.format(ca.getTime());
		return someDay;
	}

	/**
	 * 生成公钥
	 *
	 * @param pubkey
	 * @return add by yaoyuan
	 */
	public static String generatePublicKey(String pubkey) {
		// BASE64Encoder base64en = new BASE64Encoder();
		// String encode = base64en.encode(hexStringToBinary(pubkey));
		// encode = "-----BEGIN RSA PUBLIC KEY-----" + encode + "-----END RSA
		// PUBLIC KEY-----";
		// if (encode.getBytes().length < 256) {
		// encode = org.apache.commons.lang.StringUtils.rightPad(encode, 256,
		// "0");
		// }
		// return encode;
		return null;
	}

	/**
	 * 获取当前时间 精确到毫秒
	 */
	public static String getCurrentTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		String currentTime = sdf.format(new Date());
		return currentTime;
	}

	/**
	 * @功能: BCD码转为10进制串(阿拉伯数据)
	 * @参数: BCD码
	 * @结果: 10进制串
	 */
	public static String bcd2Str(byte[] bytes) {
		StringBuffer temp = new StringBuffer(bytes.length * 2);
		for (int i = 0; i < bytes.length; i++) {
			temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
			temp.append((byte) (bytes[i] & 0x0f));
		}
		return temp.toString().substring(0, 1).equalsIgnoreCase("0")
				? temp.toString().substring(1)
				: temp.toString();
	}

	/**
	 * @功能: 10进制串转为BCD码
	 * @参数: 10进制串
	 * @结果: BCD码
	 */
	public static byte[] str2Bcd(String asc) {
		int len = asc.length();
		int mod = len % 2;
		if (mod != 0) {
			asc = "0" + asc;
			len = asc.length();
		}
		byte abt[] = new byte[len];
		if (len >= 2) {
			len = len / 2;
		}
		byte bbt[] = new byte[len];
		abt = asc.getBytes();
		int j, k;
		for (int p = 0; p < asc.length() / 2; p++) {
			if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
				j = abt[2 * p] - '0';
			} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
				j = abt[2 * p] - 'a' + 0x0a;
			} else {
				j = abt[2 * p] - 'A' + 0x0a;
			}
			if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
				k = abt[2 * p + 1] - '0';
			} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
				k = abt[2 * p + 1] - 'a' + 0x0a;
			} else {
				k = abt[2 * p + 1] - 'A' + 0x0a;
			}
			int a = (j << 4) + k;
			byte b = (byte) a;
			bbt[p] = b;
		}
		return bbt;
	}

	/**
	 * 去除字符串中的符合${}形式的子串.
	 *
	 * @param
	 * @return 去除${}的字符串
	 */
	public static String escape$String(String input) {
		return input.replaceAll("\\$\\{[^}]*\\}", "");
	}

	public static String replace$String(String input, String newStr) {
		return input.replaceAll("\\$\\{[^}]*\\}", newStr);
	}

	public static String replace$SpecifyString(String input, String str,
			String newStr) {
		if (input != null) {
			input = input.replaceAll("\\$\\{" + str + "\\}", newStr);
		}
		return input;
	}

	public static String replace$String(Map<String, Object> map, String src) {
		if (src != null && map != null) {
			for (String key : map.keySet()) {
				String value = String.valueOf(map.get(key));
				src = replace$SpecifyString(src, key, value);
			}
		}
		return src;

	}

	/**
	 * 生成验证码
	 *
	 * @return
	 */
	public static String createValidateCode() {
		String str = "0,1,2,3,4,5,6,7,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D";
		String str2[] = str.split(",");// 将字符串以,分割
		String code = "";
		for (int i = 0; i < 4; i++) {
			int a = (int) (Math.random() * 36);
			code = code + str2[a];
		}
		return code;
	}

	/**
	 * 根据身份证计算年龄
	 *
	 * @param idNumber
	 * @return
	 */
	public static int calculateAgeByIdNumber(String idNumber) {
		int leh = idNumber.length();
		int years = 0;
		if (leh == 18) {
			years = Integer.parseInt(idNumber.substring(6, 10));
		} else {
			years = Integer.parseInt("19" + idNumber.substring(6, 8));
		}
		Calendar a = Calendar.getInstance();
		return a.get(Calendar.YEAR) - years;
	}

	/**
	 * 根据身份证计算性别
	 *
	 * @param idNumber
	 * @return
	 */
	public static int calculateSexByIdNumber(String idNumber) {
		int leh = idNumber.length();
		int se = 0;
		if (leh == 18) {
			se = Integer.valueOf(idNumber.substring(16, 17)) % 2;
		}
		return (se == 1 ? 1 : 2);
	}

	/**
	 * 查找数字在数组中得区间.
	 *
	 * @param sortedData
	 *            排序数组
	 * @param findValue
	 * @return
	 */
	public static int searchValueSectionInArr(Integer[] sortedData,
			int findValue) {
		int start = 0;
		int end = 0;
		for (int i = 0; i < sortedData.length; i++) {
			if (findValue >= sortedData[i]) {
				start = i;
			} else {
				end = i;
				break;
			}
		}
		return start;
	}

	/**
	 * 循环二分查找数组区间，返回第一次出现该值的位置
	 *
	 * @param sortedData
	 *            已排序的数组
	 * @param findValue
	 *            需要找的值
	 * @return 值在数组中的位置，从0开始。找不到返回-1
	 */
	public static int binarySearch(Integer[] sortedData, int findValue) {
		int start = 0;
		int end = sortedData.length - 1;

		while (start <= end) {
			// 中间位置
			int middle = (start + end) >> 1; // 相当于(start+end)/2
			// System.out.println("middle==>>" + middle);
			// 中值
			int middleValue = sortedData[middle];

			if (findValue < middleValue) {
				// 小于中值时在中值前面找
				end = middle - 1;
				// 如果小于前边的值 和前 前边的值 则继续下一次查找
				if (end >= 0) {
					int end_v = sortedData[end];
					if (findValue >= end_v) {
						return end;
					}
				} else {
					return middle;
				}
			} else {
				// 大于中值在中值后面找
				start = middle + 1;
				if (start <= sortedData.length - 1) {
					int end_v = sortedData[start];
					if (findValue < end_v) {
						return middle;
					}
				} else {
					return middle;
				}
			}
		}
		// 找不到
		return -1;
	}

	public static void main(String[] args) {

		System.out.println(StringUtils.randomUUID());
	}
}